import { ElMessage } from 'element-plus'

/**
 * 工位报警系统WebSocket管理类
 */
class AlarmWebSocket {
  constructor() {
    this.ws = null
    this.reconnectTimer = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 3000
    this.messageHandlers = new Map()
    this.isConnected = false
  }

  /**
   * 初始化WebSocket连接
   * @param {string} url WebSocket服务器地址
   */
  connect(url = 'ws://localhost:8080/alarm-system') {
    try {
      this.ws = new WebSocket(url)
      this.setupEventHandlers()
    } catch (error) {
      console.error('WebSocket连接失败:', error)
      this.handleReconnect()
    }
  }

  /**
   * 设置WebSocket事件处理器
   */
  setupEventHandlers() {
    this.ws.onopen = () => {
      console.log('工位报警系统WebSocket连接成功')
      this.isConnected = true
      this.reconnectAttempts = 0
      
      // 发送客户端注册消息
      this.send({
        type: 'client_register',
        clientType: 'alarm_display',
        timestamp: new Date().toISOString()
      })
      
      ElMessage.success('报警系统连接成功')
    }

    this.ws.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data)
        this.handleMessage(message)
      } catch (error) {
        console.error('消息解析失败:', error)
      }
    }

    this.ws.onclose = (event) => {
      console.log('WebSocket连接关闭:', event.code, event.reason)
      this.isConnected = false
      
      if (event.code !== 1000) { // 非正常关闭
        this.handleReconnect()
      }
    }

    this.ws.onerror = (error) => {
      console.error('WebSocket错误:', error)
      this.isConnected = false
    }
  }

  /**
   * 处理接收到的消息
   * @param {Object} message 消息对象
   */
  handleMessage(message) {
    const { type } = message
    
    // 调用注册的消息处理器
    if (this.messageHandlers.has(type)) {
      const handlers = this.messageHandlers.get(type)
      handlers.forEach(handler => {
        try {
          handler(message)
        } catch (error) {
          console.error(`消息处理器执行失败 [${type}]:`, error)
        }
      })
    }

    // 默认消息处理
    switch (type) {
      case 'device_alarm':
        this.handleDeviceAlarm(message)
        break
      case 'device_status_update':
        this.handleDeviceStatusUpdate(message)
        break
      case 'system_notification':
        this.handleSystemNotification(message)
        break
      case 'heartbeat':
        this.handleHeartbeat(message)
        break
      default:
        console.log('未处理的消息类型:', type, message)
    }
  }

  /**
   * 处理设备报警消息
   * @param {Object} message 报警消息
   */
  handleDeviceAlarm(message) {
    const { deviceId, deviceName, alarmType, severity, description, timestamp } = message
    
    // 显示报警通知
    const severityMap = {
      'critical': 'error',
      'warning': 'warning',
      'info': 'info'
    }
    
    ElMessage({
      type: severityMap[severity] || 'warning',
      title: '设备报警',
      message: `${deviceName} - ${description}`,
      duration: 5000,
      showClose: true
    })
    
    console.log('设备报警:', {
      deviceId,
      deviceName,
      alarmType,
      severity,
      description,
      timestamp
    })
  }

  /**
   * 处理设备状态更新
   * @param {Object} message 状态更新消息
   */
  handleDeviceStatusUpdate(message) {
    const { deviceId, status, online, timestamp } = message
    console.log('设备状态更新:', { deviceId, status, online, timestamp })
  }

  /**
   * 处理系统通知
   * @param {Object} message 系统通知消息
   */
  handleSystemNotification(message) {
    const { level, title, content } = message
    
    ElMessage({
      type: level || 'info',
      title: title || '系统通知',
      message: content,
      duration: 3000
    })
  }

  /**
   * 处理心跳消息
   * @param {Object} message 心跳消息
   */
  handleHeartbeat(message) {
    // 回复心跳
    this.send({
      type: 'heartbeat_response',
      timestamp: new Date().toISOString()
    })
  }

  /**
   * 发送消息
   * @param {Object} message 要发送的消息
   */
  send(message) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message))
    } else {
      console.warn('WebSocket未连接，消息发送失败:', message)
    }
  }

  /**
   * 注册消息处理器
   * @param {string} messageType 消息类型
   * @param {Function} handler 处理函数
   */
  onMessage(messageType, handler) {
    if (!this.messageHandlers.has(messageType)) {
      this.messageHandlers.set(messageType, [])
    }
    this.messageHandlers.get(messageType).push(handler)
  }

  /**
   * 移除消息处理器
   * @param {string} messageType 消息类型
   * @param {Function} handler 处理函数
   */
  offMessage(messageType, handler) {
    if (this.messageHandlers.has(messageType)) {
      const handlers = this.messageHandlers.get(messageType)
      const index = handlers.indexOf(handler)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    }
  }

  /**
   * 处理重连
   */
  handleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('WebSocket重连次数超过限制，停止重连')
      ElMessage.error('报警系统连接失败，请检查网络连接')
      return
    }

    this.reconnectAttempts++
    console.log(`WebSocket重连中... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
    
    this.reconnectTimer = setTimeout(() => {
      this.connect()
    }, this.reconnectInterval)
  }

  /**
   * 手动重连
   */
  reconnect() {
    this.reconnectAttempts = 0
    this.connect()
  }

  /**
   * 关闭连接
   */
  disconnect() {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
    
    if (this.ws) {
      this.ws.close(1000, '客户端主动断开')
      this.ws = null
    }
    
    this.isConnected = false
    this.messageHandlers.clear()
  }

  /**
   * 获取连接状态
   */
  getConnectionStatus() {
    return {
      isConnected: this.isConnected,
      readyState: this.ws ? this.ws.readyState : WebSocket.CLOSED,
      reconnectAttempts: this.reconnectAttempts
    }
  }

  /**
   * 发送设备控制命令
   * @param {string} deviceId 设备ID
   * @param {string} command 控制命令
   * @param {Object} params 命令参数
   */
  sendDeviceCommand(deviceId, command, params = {}) {
    this.send({
      type: 'device_command',
      deviceId,
      command,
      params,
      timestamp: new Date().toISOString()
    })
  }

  /**
   * 请求设备状态
   * @param {string} deviceId 设备ID（可选，不传则请求所有设备）
   */
  requestDeviceStatus(deviceId = null) {
    this.send({
      type: 'request_device_status',
      deviceId,
      timestamp: new Date().toISOString()
    })
  }

  /**
   * 发送报警确认
   * @param {string} alarmId 报警ID
   * @param {string} operator 操作员
   */
  acknowledgeAlarm(alarmId, operator) {
    this.send({
      type: 'alarm_acknowledge',
      alarmId,
      operator,
      timestamp: new Date().toISOString()
    })
  }
}

// 创建全局实例
const alarmWebSocket = new AlarmWebSocket()

export default alarmWebSocket
export { AlarmWebSocket }